import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

public class UDPServer {
    private static final int SERVER_PORT = 9876; // 服务器端口
    private static final int MAX_PACKET_SIZE = 203; // 最大数据包大小
    private static final double PACKET_LOSS_PROBABILITY = 0.3; // 丢包概率
    private static final byte VERSION = 2; // 版本号

    public static void main(String[] args) {
        DatagramSocket serverSocket = null;
        try {
            serverSocket = new DatagramSocket(SERVER_PORT);
            byte[] receiveData = new byte[MAX_PACKET_SIZE];
            Random random = new Random();

            System.out.println("UDP服务器已启动，端口号：" + SERVER_PORT);

            while (true) {
                DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivePacket);

                InetAddress clientAddress = receivePacket.getAddress();
                int clientPort = receivePacket.getPort();

                byte[] requestData = receivePacket.getData();
                int sequenceNumber = ((requestData[0] & 0xFF) << 8) | (requestData[1] & 0xFF);
                byte version = requestData[2];

                if (version != VERSION) {
                    System.out.println("收到无效版本号：" + version);
                    continue;
                }

                System.out.println("收到数据包：序列号=" + sequenceNumber + "，来自：" + clientAddress + ":" + clientPort);

                if (random.nextDouble() < PACKET_LOSS_PROBABILITY) {
                    System.out.println("模拟丢包，序列号=" + sequenceNumber);
                    continue;
                }

                // 准备响应数据
                byte[] responseData = new byte[MAX_PACKET_SIZE];
                responseData[0] = (byte) (sequenceNumber >> 8);
                responseData[1] = (byte) (sequenceNumber & 0xFF);
                responseData[2] = VERSION;

                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                String systemTime = sdf.format(new Date());
                byte[] timeBytes = systemTime.getBytes();
                System.arraycopy(timeBytes, 0, responseData, 3, timeBytes.length);

                DatagramPacket sendPacket = new DatagramPacket(responseData, responseData.length, clientAddress, clientPort);
                serverSocket.send(sendPacket);
                System.out.println("发送响应：序列号=" + sequenceNumber + "，到：" + clientAddress + ":" + clientPort);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        }
    }
}
